#!/usr/bin/qdroid
#codepage=Utf-8;

// Это тест-пример сравнения 2-х каталогов
// 2008.12.02-04_2030
// (а) Gasilo D.A. 2008г.
// TODO ?!- дабавить функцию обработки имени файла перед сравнением?! что бы сопоставлять файлы с разными именами.

// TODO: найти первый не отмеченный элемент
// TODO: раскрыть/свернуть все ветви
// TODO: проверка элементов для папок и групповых элементов - они зависят от опций вложенных элементов.
// TODO: возможны проблемы, если в одном каталоге - папка и в другом - файл с одинаковым именем.

var TreeWidget;//виджет - оболочка для дерева
var FList_Dir1=new t_FileList;
var FList_Dir2=new t_FileList;
 
var StrCopy="copy";
var StrDel="DELETE";
var StrNone="";

var StrAdded="added";
var StrSame=" - ";

//номера колонок
var ID_STD_COLUMN=10; //станлартно! не меняется
var ColumnDir1=1;
var ColumnDir2=2;
var ColumnCopy=3;
var ColumnDelete=4;
var CheckedCopy="V";
var CheckedDelete="X";
var UnChecked="";

//BBot доступен всегда, потому можно сразу
/**/
Dir1=BBot.app_dir()+"/test_area/dir_sample1";
Dir2=BBot.app_dir()+"/test_area/dir_sample2";
/*/
Dir1="D:/_repositories/KSR-documents/Integration_Stream/dev-office/KSR-doc";
Dir2="D:/_repositories/tmp";
/**/
//------------------------------------------------------------------------
// COPY|DELETE switchers (обработка переключений в заданной ячейке)
function edit_switchers_copy_delete(WidgetItem,Column)
{
  CurValue=WidgetItem.get_text(Column);
  
  if ( 
      (WidgetItem.get_text(ColumnDir1)!=StrAdded)
       &(WidgetItem.get_text(ColumnDir2)!=StrAdded)
     )  return 0; //нет нужды править элементы которые same в одинаковых элементов
  //print ("clicked Column="+Column+" ColumnCopy="+ColumnCopy+" CurValue="+CurValue);
  if (Column==ColumnCopy) 
      {
        if (CurValue==CheckedCopy)
          {
            WidgetItem.set_text(ColumnCopy,UnChecked);
            WidgetItem.set_column_background(ColumnCopy,"white");
          }
         else
          {
            WidgetItem.set_text(ColumnCopy,CheckedCopy);
            WidgetItem.set_column_background(ColumnCopy,"green");
            WidgetItem.set_text(ColumnDelete,UnChecked);
            WidgetItem.set_column_background(ColumnDelete,"white");
          };
      }
   else if  (Column==ColumnDelete)
      {
        if (CurValue==CheckedDelete)
          {
            //print ("UN clicked Column="+Column+" ColumnCopy="+ColumnCopy+" CurValue=["+CurValue+"] CheckedDelete=["+CheckedDelete+"]");
            WidgetItem.set_text(ColumnDelete,UnChecked);
            WidgetItem.set_column_background(ColumnDelete,"white");
          }
         else
          {
            //print ("++ clicked Column="+Column+" ColumnCopy="+ColumnCopy+" CurValue="+CurValue);
            WidgetItem.set_text(ColumnCopy,UnChecked);
            WidgetItem.set_column_background(ColumnCopy,"white");
            WidgetItem.set_text(ColumnDelete,CheckedDelete);
            WidgetItem.set_column_background(ColumnDelete,"red");
          };
      }
}

//==========================================================
// перехватчики кликов
function handler_item_double_clicked(WidgetItem,Column)
{

     // print ("double clicked Column="+Column+" ColumnCopy="+ColumnCopy);
	  		  if ( (Column==ColumnCopy)
              |(Column==ColumnDelete)
             ) //избранная колонка c "акцией"
            {
              //edit_switch_copy_delete_no(WidgetItem,Colomn);
              edit_switchers_copy_delete(WidgetItem,Column);
            }
           else
            {
            
            }; 
};
function handler_item_clicked(WidgetItem,Column)
{
      handler_item_double_clicked(WidgetItem,Column);
};

//==========================================================
// функция обработки результатов 
// перебираем элементы и выясняем что кулда надо копировать или удалять
function process_files()
{
  //перебор элементов в дереве
  var CurrentItem;
  var i;
  var ToBeDeleted; 
  var ToBeCopied; 
  var AreTheSame;
  var WasSkippedItems=0;
  var ret;
  
  var FileBot;//; // создадим манипулятор файлами
  //FileBot = new t_FileBot; // 
  // способ перебора по порядковому номеру
  item_count=TreeWidget.index_items(); //сначала составляем индекс
  print ("Tree have ["+item_count+"] items.");
  print (" Checking options... ");
  print (" ");
 
  
  for (i=0;i<item_count;i++)
   {
     //и после того как индекс составлен
     // можно обращаться к элементу по порядковому номеру
     CurrentItem=TreeWidget.indexed_item(i);
     
     AreTheSame =(CurrentItem.get_text(ColumnDir1)==StrSame)&(CurrentItem.get_text(ColumnDir2)==StrSame);
     ToBeDeleted=(CurrentItem.get_text(ColumnDelete)==CheckedDelete); 
     ToBeCopied=(CurrentItem.get_text(ColumnCopy)==CheckedCopy);
     
     if ( // надо проверить что бы мы явно указали для всех различающихся файлов что делать
          (!AreTheSame)
         &(!ToBeDeleted)
         &(!ToBeCopied)
        )
        {
           WasSkippedItems++;
           print ("Item <"+i+"> id=["+CurrentItem.get_text(ID_STD_COLUMN)+"] ");
           print ("     NOT CHECHED THAT TO DO ! ");
        };
   };//for (i=0;i<item_count;i++)
   
  // WasSkippedItems=0;//DEBUGSTOPPER! ВРЕМЕННО!!!
   if (WasSkippedItems>0)
      {
          print (" ==[ ERROR ]=================== ");
          print ("  Не все элементы отмечены ! ");
          print (" Пропущено элементов ["+WasSkippedItems+"] .");
          print ("   Обработка отменена. ");
          print (" ============================== ");
           //Close:16;
           BBot.msgbox_critical("Error.","Не могу провести синхронизацию:\n не все элемненты отмечены к обработке : Пропущено элементов ["+WasSkippedItems+"] \n Подробности см в окне сообщений.",16);
                              
      } //if (WasSkippedItems>0)
     else
      {
          print (" ==[ OK ]====================== ");
          print ("  All items are checked  ");
          print ("  we can start to process files.  ");
          print (" ============================== ");
          //Yes:2048; No: 8192; //2048+8192 
          ret=BBot.msgbox_warning("Continue?","All items are checked \n we can start to process files. \n Are you sure? \n RESULTS CAN`T BE UNDONE! \N",2048+8192);
          if (ret!=2048) 
              {
                print ("result is NO - canceling current operation.");      
                return; 
              };
          //высветим список опреаций которые надо сделать
          print ("\n Operations to be done: "+item_count);

          for (i=0;i<item_count;i++)
           {
             CurrentItem=TreeWidget.indexed_item(i);
             
             AreTheSame =(CurrentItem.get_text(ColumnDir1)==StrSame)&(CurrentItem.get_text(ColumnDir2)==StrSame);
             ToBeDeleted=(CurrentItem.get_text(ColumnDelete)==CheckedDelete); 
             ToBeCopied=(CurrentItem.get_text(ColumnCopy)==CheckedCopy);
             //print (""+i+": ");
             if (AreTheSame)
                {
                  //print ("    :: same");
                  continue;
                };
             SrcFile="";
             DestFile="";
             
             CurItem_ID=CurrentItem.get_text(ID_STD_COLUMN); //т.к. это фактически - относительный полный путь, то его и используем далее
                        // а не лезем в оригинальный элемент за опциями...
             //CurFListEl1=FList_Dir1.get(FList_Dir1.get_pos_by_id(CurItem_ID)); <<-- это если понадобится найти оригинальный элемент связанный с данным отображением. 
             //CurFListEl2=FList_Dir2.get(FList_Dir2.get_pos_by_id(CurItem_ID));
             if (CurrentItem.get_text(ColumnDir1)==StrAdded)//источник = Директория 1 
                {
                  //print ("   :: SRC=1");
                  SrcFile=Dir1+BBot.str_mid(CurItem_ID,1);//mid(1) - т.к. путь начинается с точки - текущего каталога
                  DestFile=Dir2+BBot.str_mid(CurItem_ID,1);//mid(1) - т.к. путь начинается с точки - текущего каталога
                }; 
             if (CurrentItem.get_text(ColumnDir2)==StrAdded)//источник = Директория 2 
                {
                  //print ("   :: SRC=2");
                  SrcFile=""+Dir2+BBot.str_mid(CurItem_ID,1);//mid(1) - т.к. путь начинается с точки - текущего каталога
                  DestFile=""+Dir1+BBot.str_mid(CurItem_ID,1);//mid(1) - т.к. путь начинается с точки - текущего каталога
                };
             //print (" ToBeDeleted="+ToBeDeleted+" ToBeCopied="+ToBeCopied+"");                  
             if (ToBeDeleted) 
                {
                  print (""+i+": DELETE:  file ["+SrcFile+"] \n DESABLED TEMPORALLY!");
//TEMPORALLY REMMED!                  FileBot.copy_file(SrcFile, DestFile);                  
                };
                
             if (ToBeCopied) 
                {
                  print (""+i+": COPY:\n  file ["+SrcFile+"]\n to    ["+DestFile+"] \n DESABLED TEMPORALLY!");
//TEMPORALLY REMMED!                  FileBot.copy_file(SrcFile, DestFile);
                };
           }; //for (i=0;i<item_count;i++)
           print ("\n Thatd all");
      }; //if (WasSkippedItems>0) .. ELSE ..

};//function process_files()

//==========================================================


print (" Some FileList operation demo.\n ==== COMPARE DIRECTORIES DEMO ===="); 
print (" \n ver.2008.12.04_1609 \n");

ScanDeep=10;
// при заполнении relative_paths - нужным образом заполнится ID - относит. путем.
// пути - в обратных слешах даже в виндоус!
FList_Dir1.update_from_dir(Dir1,ScanDeep);
//FList_Dir1.fill_relative_paths(BBot.app_dir()+"/test_area/dir_sample1");
FList_Dir1.fill_relative_paths(Dir1);
FList_Dir1.make_tree_struct();// добавим элементы для полного дерева если таких нет


FList_Dir2.update_from_dir(Dir2,ScanDeep);
//FList_Dir2.fill_relative_paths(BBot.app_dir()+"/test_area/dir_sample2");
FList_Dir2.fill_relative_paths(Dir2);
FList_Dir2.make_tree_struct();// добавим элементы для полного дерева если таких нет


// общий список файлов
UnitedList=new t_FileList;
UnitedList=FList_Dir2.copy();
UnitedList.unite(FList_Dir1);


// Получим список файлов добавленных в DIR1 относительно DIR2 
AddedDir1_List=new t_FileList;
AddedDir1_List=FList_Dir1.copy();
AddedDir1_List.subtract(FList_Dir2);//вычесть все что есть в множестве 2

AddedDir1_List.set_property("DIR1",StrAdded);


// Получим список файлов добавленных в DIR2 относительно DIR1 
AddedDir2_List=new t_FileList;
AddedDir2_List=FList_Dir2.copy();
AddedDir2_List.subtract(FList_Dir1);//вычесть все что есть в множестве 1

AddedDir2_List.set_property("DIR2",StrAdded);


// Получим список файлов общих для DIR1 и DIR2
Same_List=new t_FileList;
Same_List=FList_Dir2.copy();
Same_List.intersect(FList_Dir1);//пересечь множества
Same_List.set_property("DIR1",StrSame);
Same_List.set_property("DIR2",StrSame);


//добавим все это в единый список c замещением значений атрибутов  
ReplacePropertyValues = true;
UnitePropertySets = true;
UnitedList.remove_all_item_properties();

UnitedList.unite_w_properties(AddedDir1_List, ReplacePropertyValues, UnitePropertySets);
UnitedList.unite_w_properties(AddedDir2_List, ReplacePropertyValues, UnitePropertySets);
UnitedList.unite_w_properties(Same_List,      ReplacePropertyValues, UnitePropertySets);

//создадим дерево с дополнительными колонками заполняемыми из 
// атрибутов перечисленных в параметре
// примечание - для списка должен быть выполнен метод .make_tree_struct() 
TreeWidget=UnitedList.create_tree_widget("DIR1,DIR2");
TreeWidget.set_header_labels("Item,../dir_sample1,../dir_sample2/,copy,delete,,,,,,,,,,");
TreeWidget.set_colomn_header_label(0," ITEM ");
TreeWidget.set_colomn_header_label(0," ITEM ");
TreeWidget.set_colomn_width(0,150);
TreeWidget.set_colomn_width(1,100);
TreeWidget.set_colomn_width(2,100);
TreeWidget.set_colomn_width(3,40);
TreeWidget.set_colomn_width(4,40);
TreeWidget.set_column_background(3,"white");
TreeWidget.set_column_background(4,"white");

  //раскрасим заблокированные для редактирвоания элементы
  item_count=TreeWidget.index_items(); 
  for (i=0;i<item_count;i++)
   {
     CurrentItem=TreeWidget.indexed_item(i);
     AreTheSame =(CurrentItem.get_text(ColumnDir1)==StrSame)&(CurrentItem.get_text(ColumnDir2)==StrSame);
     if (AreTheSame) 
      { 
        CurrentItem.set_column_background(3,"lightgrey");
        CurrentItem.set_column_background(4,"lightgrey");
      };  
   };

//TreeWidget.item_double_clicked.connect(handler_item_double_clicked);
TreeWidget.item_clicked.connect(handler_item_clicked);
TreeWidget.enable_edittriggers(0);//запускать редактирование будем вручную по сигналу. см обработчики событий.
TreeWidget.set_selection_behavior(0);// выделять - только ячейку. для нашей задачи - это удобнее.

TreeWidget.set_size(700,500);//размерчег подправим
TreeWidget.set_pos(50,50);
TreeWidget.windowTitle="Comparing and syncronysing QDroid DEMO (2008.12.05)";
TreeWidget.show(); 

//=[pushButton1 привязки]============================================================================
// перехватчики клавиш на форме
function clicked_apply()
{
   print (" processing ...\n ");
   process_files();
}

function clicked_cancel()
{
  TreeWidget.close();
}
function clicked_help()
{
var HelpText;
HelpText=" This is a QDoid Demo script.\n\
Данный скрипт сравнивает содержимое 2-х директорий,.\
и позволяет провести синхронизацию между ними.\
 v.2008.12.05 \
 (c)2008г. ПКТБ ЦКИ ОАО РЖД.\
 (а)writed by Denjs (2008)\
 \
 \
 HOW TO USE: \
 Check and uncheck in cell in columns COPY and DELETE,   \
 and after that, press [apply] button to process changes.  \
 ";
BBot.msgbox_information("QDroid Demo script help.",HelpText,1);  
}


// настройка и привязки кнопок
TreeWidget.get_button("pushButton_1").visible=false;
TreeWidget.get_button("pushButton_2").visible=false;
TreeWidget.get_button("pushButton_3").visible=false;
TreeWidget.get_button("pushButton_4").visible=false;
ButtonApply=TreeWidget.get_button("pushButton_5");
TreeWidget.get_button("pushButton_6").visible=false;
ButtonCancel=TreeWidget.get_button("pushButton_7");
ButtonHelp=TreeWidget.get_button("pushButton_8");


ButtonApply.text="apply";
ButtonApply.clicked.connect(clicked_apply);

ButtonCancel.text="[X] CANCEL";
ButtonCancel.clicked.connect(clicked_cancel);

ButtonHelp.text="(i)help";
ButtonHelp.clicked.connect(clicked_help);

//баловство с окнами ввода
/*
BBot.inputdialog_get_item("Window header","question here!","type your text here");
BBot.inputdialog_get_item("Window header","question here!","value1,value2,value3,value4");
BBot.msgbox_information("Window header","information here!",1+2+4);
BBot.msgbox_question("Window header","question here!",1+2+4);
BBot.msgbox_warning("Window header","warning here!",1+2+4);
BBot.msgbox_critical("Window header","critical info here!",1+2+4);
*/
//BBot.messagebox("Text","InfoText","Detailes",1+2+4);
/*
Ok: 	 1
Open:	 2
Save:		 4
Cancel:	 8
Close:	 16
Discard: 32
Apply:	64
*/

//=============================================================================

return "ok";